
#include <time.h>
#include "CeBrain.h"
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

float DoTraining( int nIdx )
{
	srand(time(NULL));
	OutputAntennaRate r[INPUT_SIGNAL_COUNT*2*2*OUTPUT_SIGNAL_COUNT];
	for( int i=0; i<INPUT_SIGNAL_COUNT*2*2; i++ )
		for( int j=0; j<OUTPUT_SIGNAL_COUNT; j++ )
		{
			OutputAntennaRate tmprate = { {2,i}, j, (float)rand()/RAND_MAX/16};
			r[i+j*INPUT_SIGNAL_COUNT*2*2] = tmprate;
		}

	CeBrain eb;
	float fPassRate = eb.RunAllTrainingCase( r, INPUT_SIGNAL_COUNT*2*2*OUTPUT_SIGNAL_COUNT );

	{
		char f_name[100];
		sprintf( f_name, "RT_%d_%lf-%f.bin", nIdx, fPassRate, r[0].fRate );
		FILE* f_r = fopen( f_name, "wb+" );
		fwrite( r, sizeof(OutputAntennaRate), INPUT_SIGNAL_COUNT*2*2*OUTPUT_SIGNAL_COUNT, f_r );
		fclose( f_r );
	}

	return fPassRate;
}

float TryTraining( OutputAntennaRate *rt, int nCount )
{
	CeBrain eb;
	float fPassRate = eb.RunAllTrainingCase( rt, nCount );

	return fPassRate;
}

float TryTraining2( OutputAntennaRate *rt1,OutputAntennaRate *rt2,OutputAntennaRate *rt3,OutputAntennaRate *rt4, int nCount, OutputAntennaRate *rtTry, int nTryCount )
{
	CeBrain eb;
	float fPassRate = eb.RunAllTrainingCase2( rt1, rt2, rt3, rt4, nCount, rtTry, nTryCount );

	return fPassRate;
}

int AutoTrainingByRandom();
int AutoTrainingWithTry();
int AutoTrainingWithTry2();
int AutoTrainingByRandom2();

int main(int argc,char *argv[])
{
	if( argc>1 )
	{
		if( *argv[1] == '0')
			return AutoTrainingByRandom();
		else if( *argv[1] == '1' )
			return AutoTrainingWithTry();
		else if( *argv[1] == '2' )
			return AutoTrainingByRandom2();
		else if( *argv[1] == '3' )
			return AutoTrainingWithTry2();
	}
	printf("0 or 1 or 2\n");
}

int AutoTrainingWithTry()
{
	float fMaxPassRate = 0, fPassRate, fLastCase0Rate=0;

	OutputAntennaRate *rt;

	struct  stat nv_stat;
	int fnv = open( "RT_lastbest.bin", O_RDONLY );
	if( fnv<=0 )
	{
		printf("RT_lastbest.bin not found!\n");
		return 0;
	}
	fstat (fnv, &nv_stat);
	int nRTCount = nv_stat.st_size/sizeof(OutputAntennaRate);
	rt = new OutputAntennaRate[ nv_stat.st_size/sizeof(OutputAntennaRate)];
	close( fnv );

	FILE* fNv = fopen( "RT_lastbest.bin", "rb+" );
	fread( rt, sizeof(OutputAntennaRate), nRTCount, fNv );
	fclose( fNv );

DOTRY:
	for( int i=0; i<nRTCount; i++ )
	{
		fMaxPassRate = 0;
		float GoodRate=0, lastrate = rt[i].fRate;
		float trystep = rt[i].fRate/20.0;
		float trystep2 = (1-rt[i].fRate)/10.0;
		printf("==step %f, step2 %f, last %f\n", trystep, trystep2, lastrate);

		if( trystep >= 0.0001 )
		{
			for( float t=0; t<lastrate; t+=trystep )
			{
				rt[i].fRate = t;
				fPassRate = TryTraining( rt, nRTCount );
				if( fPassRate > fMaxPassRate )
				{
					fMaxPassRate = fPassRate;
					GoodRate = t;
				}
				printf("Try at %d, rate %f, pass %f\n", i, t, fPassRate);
			}
		}

		if( trystep2 >= 0.0001 )
		{
			for( float t=lastrate; t<1; t+=trystep2 )
			{
				rt[i].fRate = t;
				fPassRate = TryTraining( rt, nRTCount );
				if( fPassRate > fMaxPassRate )
				{
					fMaxPassRate = fPassRate;
					GoodRate = t;
				}
				printf("Try2 at %d, rate %f, pass %f\n", i, t, fPassRate);
			}
		}
		rt[i].fRate = GoodRate;

		{
			char f_name[100];
			sprintf( f_name, "RT_%d_%f.bin", i, fMaxPassRate );
			FILE* f_r = fopen( f_name, "wb+" );
			fwrite( rt, sizeof(OutputAntennaRate), nRTCount, f_r );
			fclose( f_r );
		}

		if( i==0 )
		{
			if( fLastCase0Rate==0 )
				fLastCase0Rate = fMaxPassRate;
			else if(fLastCase0Rate < fMaxPassRate)
				fLastCase0Rate = fMaxPassRate;
			else
			{
				printf("fLastCase0Rate is %f, current is %f\n", fLastCase0Rate,fMaxPassRate);
				return -1;
			}
		}
	}
	if( fMaxPassRate<99 )
		goto DOTRY;
	return 0;
}

int AutoTrainingByRandom()
{
	float fMaxPassRate = 0, fPassRate;
	int nIdx = 0;
	for(int i=0; i<100; i++)
	{
		fPassRate = DoTraining(i);
		if( fPassRate > fMaxPassRate )
		{
			fMaxPassRate = fPassRate;
			nIdx = i;
		}
	}
	printf("MaxRate is %f, at %d\n", fMaxPassRate, nIdx);
	return 0;
}

float DoRandomTraining( int nIdx )
{
    OutputAntennaRate *rt1, *rt2, *rt3, *rt4;

    int nRTCount = 32*9;
    rt1 = new OutputAntennaRate[ nRTCount ];
    rt2 = new OutputAntennaRate[ nRTCount ];
    rt3 = new OutputAntennaRate[ nRTCount ];
    rt4 = new OutputAntennaRate[ nRTCount ];

    FILE* fNv = fopen( "rt_part1.bin", "rb+" );
    if( fNv==NULL )
    {
            TRACE("rt_part1.bin not found!\n");
            return 0;
    }
    fread( rt1, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part2.bin", "rb+" );
    fread( rt2, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part3.bin", "rb+" );
    fread( rt3, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part4.bin", "rb+" );
    fread( rt4, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );


	srand(time(NULL));
	OutputAntennaRate r[OUTPUT_SIGNAL_COUNT*4];
	for( int i=0; i<OUTPUT_SIGNAL_COUNT*4; i++ )
	{
		OutputAntennaRate tmprate = { {3,i}, 0, (float)rand()/RAND_MAX/4};
		r[i] = tmprate;
	}

	CeBrain eb;
	float fPassRate = eb.RunAllTrainingCase2( rt1,rt2,rt3,rt4, nRTCount, r, OUTPUT_SIGNAL_COUNT*4 );

	{
		char f_name[100];
		sprintf( f_name, "RT_%d_%lf-%f.bin", nIdx, fPassRate, r[0].fRate );
		FILE* f_r = fopen( f_name, "wb+" );
		fwrite( r, sizeof(OutputAntennaRate), OUTPUT_SIGNAL_COUNT*4, f_r );
		fclose( f_r );
	}

	return fPassRate;

}

int AutoTrainingByRandom2()
{
	float fMaxPassRate = 0, fPassRate;
	int nIdx = 0;
	for(int i=0; i<100; i++)
	{
		fPassRate = DoRandomTraining(i);
		if( fPassRate > fMaxPassRate )
		{
			fMaxPassRate = fPassRate;
			nIdx = i;
		}
	}
	printf("MaxRate is %f, at %d\n", fMaxPassRate, nIdx);
	return 0;
}

int AutoTrainingWithTry2()
{
	float fMaxPassRate = 0, fPassRate, fLastCase0Rate=0;
    OutputAntennaRate *rt1, *rt2, *rt3, *rt4;

    int nRTCount = 32*9;
    rt1 = new OutputAntennaRate[ nRTCount ];
    rt2 = new OutputAntennaRate[ nRTCount ];
    rt3 = new OutputAntennaRate[ nRTCount ];
    rt4 = new OutputAntennaRate[ nRTCount ];

    FILE* fNv = fopen( "rt_part1.bin", "rb+" );
    if( fNv==NULL )
    {
            TRACE("rt_part1.bin not found!\n");
            return 0;
    }
    fread( rt1, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part2.bin", "rb+" );
    fread( rt2, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part3.bin", "rb+" );
    fread( rt3, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );
    fNv = fopen( "rt_part4.bin", "rb+" );
    fread( rt4, sizeof(OutputAntennaRate), nRTCount, fNv );
    fclose( fNv );

	OutputAntennaRate r[OUTPUT_SIGNAL_COUNT*4];
	fNv = fopen( "rt_lastbest.bin", "rb+" );
	if( fNv==NULL )
	{
		TRACE("rt_lastbest.bin not found!\n");
		return 0;
	}
	fread( r, sizeof(OutputAntennaRate), OUTPUT_SIGNAL_COUNT*4, fNv );
	fclose( fNv );

	//CeBrain eb;
	//float fPassRate = eb.RunAllTrainingCase2( rt1,rt2,rt3,rt4, nRTCount, r, OUTPUT_SIGNAL_COUNT*4 );
	DOTRY:
		for( int i=0; i<OUTPUT_SIGNAL_COUNT*4; i++ )
		{
			fMaxPassRate = 0;
			float GoodRate=0, lastrate = r[i].fRate;
			float trystep = r[i].fRate/20.0;
			float trystep2 = (1-r[i].fRate)/10.0;
			printf("==step %f, step2 %f, last %f\n", trystep, trystep2, lastrate);

			if( trystep >= 0.0001 )
			{
				for( float t=0; t<lastrate; t+=trystep )
				{
					r[i].fRate = t;
					fPassRate = TryTraining2( rt1,rt2,rt3,rt4, nRTCount, r, OUTPUT_SIGNAL_COUNT*4 );
					if( fPassRate > fMaxPassRate )
					{
						fMaxPassRate = fPassRate;
						GoodRate = t;
					}
					printf("Try at %d, rate %f, pass %f\n", i, t, fPassRate);
				}
			}

			if( trystep2 >= 0.0001 )
			{
				for( float t=lastrate; t<1; t+=trystep2 )
				{
					r[i].fRate = t;
					fPassRate = TryTraining2( rt1,rt2,rt3,rt4, nRTCount, r, OUTPUT_SIGNAL_COUNT*4 );
					if( fPassRate > fMaxPassRate )
					{
						fMaxPassRate = fPassRate;
						GoodRate = t;
					}
					printf("Try2 at %d, rate %f, pass %f\n", i, t, fPassRate);
				}
			}
			r[i].fRate = GoodRate;

			{
				char f_name[100];
				sprintf( f_name, "RT_%d_%f.bin", i, fMaxPassRate );
				FILE* f_r = fopen( f_name, "wb+" );
				fwrite( r, sizeof(OutputAntennaRate), OUTPUT_SIGNAL_COUNT*4, f_r );
				fclose( f_r );
			}

			if( i==0 )
			{
				if( fLastCase0Rate==0 )
					fLastCase0Rate = fMaxPassRate;
				else if(fLastCase0Rate < fMaxPassRate)
					fLastCase0Rate = fMaxPassRate;
				else
				{
					printf("fLastCase0Rate is %f, current is %f\n", fLastCase0Rate,fMaxPassRate);
					return -1;
				}
			}
		}
		if( fMaxPassRate<99 )
			goto DOTRY;
		return 0;

	return fPassRate;

}
